-------------------------------------------------------------------------------
-- Design Name: hw2_top.vhd
-- Author: Aaron Baxter
-- Design Overview: Hierachial design that implements a priority encoder based 
-- on the four input buttons that controls a 2x2 switch that will light the leds
-- and/or the 7 segment decoder based on two sets of 3 inputs from the switches.
-- Outputs a valid signal on Led 7 when the priority encoder is valid.
-- All outputs are registered.

-- Synthesis Results: Warning on sw6 being unused.  

-- Utilization:
-- Flip Flops: 3
-- LUTs: 16
-- Slices: 9

-- Functionality: Works as specified
-------------------------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity hw2_top is
    Port ( 
			clk 	: in  	STD_LOGIC;
			btn 	: in  	STD_LOGIC_VECTOR (3 downto 0);
			sw 		: in  	STD_LOGIC_VECTOR (7 downto 0);
			seg 	: out  	STD_LOGIC_VECTOR (6 downto 0);
			dp	 	: out  	STD_LOGIC;
			an	 	: out  	STD_LOGIC_VECTOR (3 downto 0);
			Led 	: out  	STD_LOGIC_VECTOR (7 downto 0)
		);
end hw2_top;

architecture Behavioral of hw2_top is

	COMPONENT seg_decoder 
	Port ( 
		dec_in 	: in   STD_LOGIC_VECTOR (2 downto 0);
		seg 	: out  STD_LOGIC_VECTOR (6 downto 0)
		);
	end COMPONENT;

	COMPONENT priority_encoder
	PORT(
		p_en_in : IN std_logic_vector(3 downto 0);          
		enc_out : OUT std_logic_vector(1 downto 0);
		valid : OUT std_logic
		);
	END COMPONENT;

	COMPONENT switch_x2
	PORT(
		p_en : IN std_logic_vector(1 downto 0);
		x1 : IN std_logic_vector(2 downto 0);
		x2 : IN std_logic_vector(2 downto 0);          
		y1 : OUT std_logic_vector(2 downto 0);
		y2 : OUT std_logic_vector(2 downto 0)
		);
	END COMPONENT;

	signal y1 : std_logic_vector(2 downto 0);
	signal y2 : std_logic_vector(2 downto 0);
	signal dec_in : std_logic_vector(2 downto 0);
	signal enc_out : std_logic_vector(1 downto 0);
	signal valid : std_logic;

begin

	Led (6 downto 3) <= "0000"; -- unused LEDs

	dp <= '1';					-- unused decimal point
	an <= "1110";				-- light the right most seven segment

	seg_1: seg_decoder PORT MAP(
			dec_in => dec_in,
			seg => seg
		);

	p_en_1: priority_encoder PORT MAP(
		p_en_in => btn,
		enc_out => enc_out,
		valid => valid
	);

	sw_x2: switch_x2 PORT MAP(
		p_en => enc_out,
		x1 => sw (2 downto 0),
		x2 => sw (5 downto 3),
		y1 => y1,
		y2 => y2
	);
	
	-- allow reset of outputs and to register outputs based off clock
	process (sw(7), clk)
	begin
		--reset
		if sw(7) = '1' then
			dec_in	<= "000";
			Led (7)	<= '0';
			Led (2 downto 0) <= "000";
		
		--clock outputs
		elsif rising_edge(clk) then
			Led (7) <= valid;
			Led (2 downto 0) <= y1;
			dec_in <= y2;
		
		end if;
	end process;

end Behavioral;

-----------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity seg_decoder is
    Port ( 
			dec_in 	: in  STD_LOGIC_VECTOR (2 downto 0);
			seg 	: out  STD_LOGIC_VECTOR (6 downto 0)
		);
end seg_decoder;

architecture Behavioral of seg_decoder is
begin
	-- 3 input to segment mapping (0-7)
	with dec_in select
		seg	<= 		"1000000" when "000",
					"1111001" when "001",
					"0100100" when "010",
					"0110000" when "011",
					"0011001" when "100",
					"0010010" when "101",
					"0000010" when "110",
					"1111000" when "111",
					"0000000" when others;


end Behavioral;

-----------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity priority_encoder is
    Port ( 
			p_en_in 	: in   STD_LOGIC_VECTOR (3 downto 0);
			enc_out		: out  STD_LOGIC_VECTOR (1 downto 0);
			valid		: out  STD_LOGIC 
		);
end priority_encoder;

architecture Behavioral of priority_encoder is
begin
	-- outputs the most significant button being pressed, encoded
	process(p_en_in)
		begin
			if p_en_in(3) = '1' then
				enc_out <= "11";
				valid	<= '1';
			elsif p_en_in(2) = '1'  then
				enc_out <= "10";
				valid	<= '1';
			elsif p_en_in(1) = '1'  then
				enc_out <= "01";
				valid	<= '1';
			elsif p_en_in(0) = '1'  then
				enc_out <= "00";
				valid	<= '1';
			else -- no buttons being pressed, clear the valid flag
				enc_out <= "00";
				valid	<= '0';
			end if;
	end process;

end Behavioral;

-----------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity switch_x2 is
    Port ( 
			p_en 	: in  STD_LOGIC_VECTOR (1 downto 0);
			x1 		: in  STD_LOGIC_VECTOR (2 downto 0);
			x2		: in  STD_LOGIC_VECTOR (2 downto 0);
			y1		: out  STD_LOGIC_VECTOR (2 downto 0);
			y2		: out  STD_LOGIC_VECTOR (2 downto 0)
		);
end switch_x2;

architecture Behavioral of switch_x2 is
begin

	-- uses two inputs to swap x inputs to y inputs accordingly
	process(p_en, x1, x2)
		begin	
			case p_en is
				when "00" =>	y1 <= x1; y2 <= x2;
				when "01" =>	y1 <= x2; y2 <= x1;
				when "10" =>	y1 <= x1; y2 <= x1;
				when "11" =>	y1 <= x2; y2 <= x2;
				when others =>	y1 <= "000"; y2 <= "000";
			end case;
	end process;

end Behavioral;








